

#include "main.h"
#include "lcd.h"
#include "sc-s.h"
#include <stdlib.h>
#include "trans-s.h"
#include <avr/power.h>
#include <avr/sleep.h>

u16 v_tmp = 4950;
u16 v_aku = 0;
u16 v_pow = 0;
u16 v_dc = 0;
volatile u16 TimerH = 0;
u16 leg_date = 0x1421;
u16 napa = 100;
u16 napb = 100;

u8 awp_flags = 0;
u8 cur = 0;
char pin[4] = "0000";

#define LCD_TIMEOUT	180

u8 lcdout = 0;
u8 init_display = 0;
extern u8 sh_flag;

i16 p_off;		// power offset kalib
i16 a_off;		// aku_offset kalib


void work()
{
#if defined (MEDIA_PS) || defined(MEDIA_PD)
	Awp = 0;
#endif
	if (init_display)
	{ 
		init_display = 0;
		LCD_VCC_ON;
		WAITMS(50);
		lcd_init();
		lcd_clear();
		lcdout = 0;
	}
	
	switch(Pro)
	{
		case PRO_WORK:
			show_media(meas,0);
		break;
		case PRO_SERWIS:
			serwis_loop();
		break;
		case PRO_CALIB:
			Awp = 0;
#ifndef MEDIA_PS
			kalib_routin();
#endif
		break;
		case PRO_CALIB_WAIT:
#ifdef MEDIA_PS
		Pro = PRO_WORK;
#else
			kalib_wait();
#endif
		break;
		case PRO_CONFIG:
			config_menu();
		break;
		case PRO_OFF:
			off_routine();
		break;
		case PRO_PARAM:
			show_param();			
	}
	//uout = 1;
	check_input(0);
	

	aku_check();

	awp_check();
	
	if (lcdmode)
	{
		lcdout = 0;
	}
	else
	{
		if (Pro == PRO_WORK)
		{
			lcdout++;
			if (lcdout > LCD_TIMEOUT)
			{
				lcdout = LCD_TIMEOUT;
			
				LCD_VCC_OFF;
			}
		}
		else
		{
			lcdout = 0;
		}
		
		if (!ENT || !MIN || !PLU)
		{
			if (lcdout > LCD_TIMEOUT - 1)
			{
				init_display = 0;
				LCD_VCC_ON;
				WAITMS(50);
				lcd_init();
				lcd_clear();
			}
			lcdout = 0;
		}
	}
	
	
	static u8 blink = 0;
	blink ++;
	
	if (blink > 25)
	{
		blink = 0;
		
		/*
		if ((PORTD & 0xC0) != 0xC0)		// alarms on
		{
			if (!(PORTD & (1 << 7)))
			{
				LED_A_ON;
				WAITMS(9);
				LED_A_OFF;
				WAITMS(45);
				
			}
			LED_A_ON;
		}
		WAITMS(9);
		LED_A_OFF;
		LED_W_ON;
		WAITMS(15);
		LED_W_OFF;
		
		if (!(PINA & (1 << 2)))
		{
			WAITMS(25);
			LED_W_ON;
			WAITMS(25);
			LED_W_OFF;
			WAITMS(25);
			LED_W_ON;
			WAITMS(25);
			LED_W_OFF;
		}
		
		if (ksp_error)
		{
			ksp_error = 0;
			lcd_home();
			lcd_print("ZAP/KSP3");
			init_display = 1;
			WAITMS(3000);
		}
		*/
	}
	
	
	
}

#define DEF_TIME_POWER_WAIT	150

u8 check_input(u8 force)
{
	static u8 last_state = 0xAA;
	u8 state;
	if (PINA & (1 << 2))
	{
		state = 0; 
	}
	else
	{
		state = 4;							// 3rd bit
	}
	
	state |= ( PIND & (1 << 7) ) >> 6;		// 1st bit
	state |= ( PIND & (1 << 6) ) >> 6;		// sec bit
	

	if (state != last_state || force)
	{

		//if (!tk_addr)
		//{
			tk_addr = K_ADDR_INPUT;
			tk_data = state;
			tk_repeat = 3;
			last_state = state;
		//}
		

	
	}
	return state;
	
}

void aku_check()
{
	static u8 blink = 0;
	
	static u8 flag = 0;
	static u8 hold = 0;

	static u8 reset_flag = 0;
	
	u16 aku = v_aku + ( a_off - 2048);
	u16 pow = v_pow + ( p_off - 2048);
	
	float ilad = 0;
	if (pow > aku)
	{
		ilad = (float)(pow - aku) / 0.0056;
	}
	else
	{
		ilad = 0;
	}
	
	
	if (blink > 15)
	{
		blink = 0;
	}
	
	if (PINA & 0x02)
	{
		hold = 0;
		if (aku  < 9500)
		{
			init_display = 1;
			LCD_VCC_ON;
			WAITMS(50);
			lcd_init();
			lcd_clear();
			LED_W_ON;
			LED_A_ON;
			lcd_print("!LOWBAT!");
			WAITMS(3000);
			lcd_home();
			lcd_print("!WYLACZAM!");
			WAITMS(1500);
			PORTA &= ~(1 << 6);
			WAITMS(100);
			PORTA |= ( 1 << 6);
			LED_W_OFF;
			LED_A_OFF;
			return;
		}
		
		if (aku < 9800)
		{
			blink++;
			if (blink == 1)
			{
				init_display = 1;
				LCD_VCC_ON;
				WAITMS(50);
				lcd_init();
				lcd_clear();
				lcd_print("  AKU!  ");
				WAITMS(500);
				init_display = 1;
				//return;
			}
		}
		
		//if ( aku >= pow - 10 )
		if ( ilad < 13000 )		// 13mA
		{
			blink++;
			if (blink == 5)
			{
				if (!Kcl)
				{
					AWP_RSET_POWERFLAG;
					blink = 0;
				}
				else
				{
					AWP_SET_POWERFLAG;
					if (Pro == PRO_WORK)
					{
						init_display = 1;
						LCD_VCC_ON;
						WAITMS(50);
						lcd_init();
						lcd_clear();
						lcd_print("BRAK ZAS.");
						if (!reset_flag)
						{
							tk_addr = K_ADDR_RS_ASKNUM;
						}
						reset_flag = 1;
						WAITMS(500);
					}
					flag = DEF_TIME_POWER_WAIT;
					return;
				}
			}
			
		}
		else
		{
			if (!Kcl)
			{
				AWP_RSET_POWERFLAG;
				blink = 0;
			}
			else
			{
				blink++;
				if (blink == 3)
				{
					//blink = 12;	/// 12->15->0->3
					AWP_SET_POWERFLAG;
					if (Pro == PRO_WORK)
					{
						init_display = 1;
						LCD_VCC_ON;
						WAITMS(50);
						lcd_init();
						lcd_clear();
						lcd_print("ZAM.POL.");
						//WAITMS(500);
						WAITMS(50);
						if (!reset_flag)
						{
							tk_addr = K_ADDR_RS_ASKNUM;
						}
						reset_flag = 1;
					}
					flag = DEF_TIME_POWER_WAIT;
					return;
				}
			}
		}
	}
	else
	{
		hold ++;
		if (hold > 40)
		{
			hold = 40;
			blink = 0;
			
		}
		
		if (flag < DEF_TIME_POWER_WAIT - 20)
		{
			reset_flag = 0;
		}
		if (flag)
		{
			flag--;
			AWP_SET_POWERFLAG;
		}
		if (!flag)
		{
			AWP_RSET_POWERFLAG;
		}
	}
	
	
}


void check_keyboard()
{
	static u8 kal = 0;
	static u8 param = 0;
	static u8 wysokie = 0;
	static u8 off = 0;
	
	if (!PLU && !ENT && MIN && (Pro == PRO_WORK))
	{
		kal ++;
	}
	else
	{
		kal = 0;
	}
	
	if (!PLU && ENT && MIN && (Pro == PRO_WORK))
	{
		param ++;
	}
	else
	{
		param = 0;
	}
	
	if (PLU && !ENT && !MIN && (Pro == PRO_WORK))
	{
		off ++;
	}
	else
	{
		off = 0;
	}

#ifdef MEDIA_CH4
	if (PLU && ENT && !MIN && (Pro == PRO_WORK))
	{
		wysokie ++;
	}
	else
	{
		wysokie = 0;
	}
#endif
	if (kal > 11 && (Pro == PRO_WORK))
	{
#ifdef MEDIA_CH4IR
/*
		if (!(meas & (1 << 14)))
		{
			lcd_home();
			lcd_print("Init !!!");
			WAITMS(1500);
			kal = 0;
			return;
		}
*/
#endif
		
		
		kal = 0;
		Pro = PRO_CALIB_WAIT;
		lcd_home();
		lcd_print(" CZEKAJ ");
		WAITMS(400);
		while (!PLU || !MIN || !ENT);
		cur = 0;
		strcpy(pin,"0000");
		
		resetStartTimer();
		cal_wait_flag = 1;
		tk_data = 0;
		tk_addr = K_ADDR_CAL_START;
	

	}
	
	if (param > 10 && (Pro == PRO_WORK))
	{
		param = 0;
		Pro = PRO_PARAM;
	}
	
	
	if (wysokie > 15 && (Pro == PRO_WORK))
	{
		wysokie = 0;
		lcd_home();
		lcd_print("WYSOKIE!");
		tp_data = 77;
		tp_addr = P_ADDR_SW_HRANGEUSER;
		WAITMS(5000);
	}
	
	if (off > 7 && (Pro == PRO_WORK))
	{
		off = 0;
		Pro = PRO_OFF;
	}

}

void setup_io()
{
	
	DDRA = 0;
	DDRA &= ~BIT(0); ///????
	DDRA &= ~BIT(1); // ladowanie
	DDRA &= ~BIT(2); // zestyk wylacz (wejscie)
	DDRA &= ~BIT(3); // enter
	DDRA &= ~BIT(4); // +
	DDRA &= ~BIT(5); // -
	DDRA |= (1 << 6);		// zalaczenie
	DDRA |= (1 << 7);// led praca
	
	DDRB = 0;
	DDRB |= BIT(0);	// LTC 1446 cs
	DDRB |= BIT(1);	// LTC 1446 clk
	DDRB &= ~BIT(2);	//NC
	DDRB |= BIT(3);	// LTC 1446 vcc
	DDRB |= BIT(4);	// LTC 1446 din
	//DDRB |= BIT(5);	//LED Y
	//DDRB |= BIT(6);	//LED R
	DDRB |= BIT(7);		// HIGH/LOW Current source

	PORTB |= (1 << 7);		// default high current
	
	DDRD = 0;
	//PORTD = 0 | ( 1 << 3);		// set PCK HIGH	// do not pull it high - 
	DDRD |= (1 << 5);		// portd.5 - PTX
	DDRD |= (1 << 3);		// portd.3 - PCK			// Proc P is pulling it high
	DDRD |= (1 << 1);		// portd.1 - KTX
	/// D - TRANS // later
	PORTD |= ( 1 << 2) | ( 1 << 0) | (1 << 1) | ( 1 << 3) | (1 << 4) | (1 << 5);		// pullup lines for K-proc
	
	DDRC = 0xFF;		// LCD PINS (whole PORTC)
	LCD_VCC_ON;
	// PORTC.0 -> LED_ALARM
	
	PORTA |= (1 << 3) | (1 << 4) | (1 << 5) | (1 << 6) | (1 << 7) | ( 1 << 2);
	PORTB = 0;
	
	lcd_setio();
	lcd_init();

	_SFR_MEM8(0x64) = (1 << PRTWI)  | (1 << PRUSART0) | (1 << PRSPI) | (1 << PRADC) ; //PPR
	
	// wake me up timer
	OCR2A = 200;			// 1024us * 200 = 200ms wakeup call + trans_s->p
	TCCR2A = (1 << WGM21);		// CTC (OCR2A)
	//TCCR2B = 6;		// DIV 256
	TCCR2B = 7;		// DIV 1024
	TIMSK2 |= ( 1 << OCIE2A );
	
 
	
}



#define INTRO_DELAY	1000

#ifdef MEDIA_CH4
void display_name()
{
	lcd_print(" SC-CH4 ");
}

void display_alarms()
{
	char str[8];
	lcd_home();
	lcd_print("AL1:");
	fuse2(str,AL1);
	lcd_print(str);
	WAITMS(INTRO_DELAY);

	lcd_home();
	lcd_print("AL2:");
	fuse2(str,AL2);
	lcd_print(str);
	WAITMS(INTRO_DELAY);
}

#elif defined MEDIA_CO2
void display_name()
{
	lcd_print(" SC-CO2 ");
}

void display_alarms()
{
	char str[8];
	lcd_home();
	lcd_print("AL1:");
	fuse2(str,AL1);
	lcd_print(str);
	WAITMS(INTRO_DELAY);

	lcd_home();
	lcd_print("AL2:");
	fuse2(str,AL2);
	lcd_print(str);
	WAITMS(INTRO_DELAY);
}
#elif defined(MEDIA_CH4IR)

 void display_name()
{
	lcd_print("SC-CH4IR");
}

void display_alarms()
{
	char str[8];
	lcd_home();
	lcd_print("AL1:");
	fuse2(str,AL1);
	lcd_print(str);
	WAITMS(INTRO_DELAY);

	lcd_home();
	lcd_print("AL2:");
	fuse2(str,AL2);
	lcd_print(str);
	WAITMS(INTRO_DELAY);
}

#endif




void intro()
{
	char str[16];
	
	_delay_ms(100);
	lcd_init();
	_delay_ms(10);
	lcd_clear();



	CUR_SW_HIGH;
	display_name();

	ALARM1_ON;
	ALARM2_ON;
	
	WAITMS(1600);

	LED_A_OFF;
	LED_W_OFF;

	ALARM1_OFF;
	ALARM2_OFF;

	
	if (!ENT && !MIN)
	{
		load_routine();
	}
	
	
	
	lcd_clear();
	lcd_print("nr:");
	char buff[8];
	
	itoa(Nr,buff,10);
	
	lcd_print(buff);
	tk_data = Nr;
	tk_addr = K_ADDR_NR;
	
	WAITMS(INTRO_DELAY);
	if (!PLU)
	{
		return;			// skip intro
	}
	
	lcd_home();
	lcd_print(VER);
#if defined (MEDIA_PS) || defined(MEDIA_PD)
	tk_addr = K_ADDR_HRANGE;
	tk_data = pr_range_h;
#endif
	
	WAITMS(INTRO_DELAY);
	
	lcd_home();
	if (Ksp == 0)
	{
		lcd_print("  BRAK  ");
		tk_data = 0;
	}
	if (Ksp == 1)
	{
		lcd_print(" KSP-2  ");
		tk_data = 0;
	}
	if (Ksp == 2)
	{
		lcd_print(" KSP-3  ");
		tk_data = 1;
		
#ifndef MEDIA_HCUR
		CUR_SW_LOW;
#endif
		
	}
	tk_addr = K_ADDR_KSP;
	
	WAITMS(INTRO_DELAY);
	if (!ENT)
	serwis_flag = 1;
	else
	serwis_flag = 0;


#if defined (MEDIA_PS) || defined(MEDIA_PD)

	tk_addr = K_ADDR_LRANGE;
	tk_data = pr_range_l;

	display_alarms();
#else
	lcd_home();
	lcd_print("AWP ");
	if (Awp)
	lcd_print("ZAL ");
	else
	lcd_print("WYL ");
	WAITMS(INTRO_DELAY);

	if (Awp)
	{
		display_alarms();
	}
#endif

	
	lcd_home();
	lcd_print("KCL ");
	if (Kcl)
	lcd_print("ZAL ");
	else
	lcd_print("WYL ");
	WAITMS(INTRO_DELAY);

	lcd_home();
	lcd_print("WY-U ");
	if (uout)
	lcd_print("ZAL ");
	else
	lcd_print("WYL ");
	WAITMS(INTRO_DELAY);


	lcd_home();
	lcd_print("LCD ");
	if (lcdmode)
	lcd_print("ZAL ");
	else
	lcd_print("TIME");
	WAITMS(INTRO_DELAY);

	u16 aku = v_aku + ( a_off - 2048);
	//u16 pow = v_pow + ( p_off - 2048);	// unused
	
	
	
	lcd_home();
	lcd_print("AKU:");
	fuse2(str,aku / 10);
	lcd_print(str);
	WAITMS(INTRO_DELAY);
	
	lcd_home();
	lcd_print("KONFIG? ");
	u8 c = 0;
	for (c = 0; c < 200; c++)
	{
		if ((!(MIN)) && (!(PLU)))
		{
			if (!serwis_flag)
			{
				Pro = PRO_CONFIG;
				calib_ptr_deep = 0;
				return;
			}
			Pro = PRO_SERWIS;
			return;
		}
		WAITMS(10);
	}
}

#define PIN_SERWIS	2512
#define PIN_CALIB	1979

void pin_display(char* pin, u8 cur)
{
	static u8 blink = 0;
	
	lcd_home();
	lcd_print("PIN:");
	
	if (cur)
	for (u8 c = 0; c < cur; c++)
		lcd_print("*");
	
	char str[2];
	str[1] = 0;
	
	if (!PLU || !MIN)
		blink = 0;
	
	blink ++;
	if (blink < 3)
	{
		str[0] = pin[cur];
		lcd_print(str);
	}
	else
	{
		blink = 0;
		lcd_print("#");
	}
	
	
	
	for (u8 c = 0; c < 3 - cur;c ++)
	lcd_print("*");
	
}


void pin_loop()
{
	static u8 wait = 0;
	
	if (!PLU)
	{
		pin[cur]++;
		if (pin[cur] > '9')
		pin[cur] = '0';
		wait = 4;
	}
	
	if (!MIN)
	{
		pin[cur]--;
		if (pin[cur] < '0')
		pin[cur] = '9';
		wait = 4;
	}
	if (wait)
		wait--;
	
	if (!ENT && !wait)
	{
		cur++;
		if (cur == 4)
		{
			cur = 0;
			u16 pin_val = atoi(pin);
			
			if (pin_val == ref_pin)
			{
				pin_ok = 1;
				return;
			}
			else
			{
				pin_ok = 255;	// bad
				return;
			}
			
		}
	}
	pin_display(pin,cur);
	while((!ENT));

}

void _write(u16 uiAddress, u8 ucData)
{

	while(EECR & (1<<EEPE));
	EEAR = uiAddress;
	EEDR = ucData;
	EECR |= (1<<EEMPE) ;
	EECR |= (1<<EEPE) ;

}

unsigned char _read(u16 uiAddress)
{
	while(EECR & (1<<EEPE));
	EEAR = uiAddress;
	EECR |= (1<<EERE);
	_delay_us(30);
	return EEDR;
}


double read_double(u8 addr)
{
	char dbf[4];
	
	for (u8 c = 0; c < 4; c++)
	{
		dbf[c] = _read(addr + c);
	}
	
	double *result = (double*)&dbf;
	return *result;
	
}

void write_double(u8 addr, double val)
{
	char *dbf;
	dbf = (char*)&val;
	
	for (u8 c = 0; c < 4; c++)
	{
		_write(addr + c,dbf[c]);
	}
}

void write_word(u16 addr, u16 val)
{
	char *dbf;
	dbf = (char*)&val;
	
	for (u8 c = 0; c < 2; c++)
	{
		_write(addr + c,dbf[c]);
	}
}

u16 read_word(u16 addr)
{
	char dbf[4];
	
	for (u8 c = 0; c < 2; c++)
	{
		dbf[c] = _read(addr + c);
	}
	
	u16 *result = (u16*)&dbf;
	return *result;
	
}


#ifdef MEDIA_CH4
#define EEP_FLAG	71
#elif MEDIA_CH4IR
#define EEP_FLAG	70
#elif MEDIA_CON
#define EEP_FLAG	72
#elif MEDIA_COS
#define EEP_FLAG	79
#elif MEDIA_CO2
#define EEP_FLAG	99
#elif MEDIA_PS
#define EEP_FLAG	105
#elif MEDIA_PD
#define EEP_FLAG	103
#elif MEDIA_O2
#define EEP_FLAG	104
#endif

void init_eeprom()
{
	u8 ee = 0;
	ee = _read(0);
	
	AL1 = 100;
	AL2 = 200;

#if   defined(MEDIA_CH4) || defined (MEDIA_CH4IR)
AL1 = 150;
AL2 = 200;
stn = 198;
#elif defined(MEDIA_CON)
AL1 = 18;
AL2 = 26;
stn = 158;
#elif defined(MEDIA_COS)
AL1 = 18;
AL2 = 26;
stn = 820;
#elif defined(MEDIA_O2)
AL1 = 195;
AL2 = 190;
stn = 207;
#elif defined(MEDIA_CO2)
AL1 = 50;
AL2 = 100;
stn = 210;
#elif defined(MEDIA_PS)

#elif defined(MEDIA_PD)

#else
	cli();
	lcd_home();
	lcd_print(" MEDIA? ");
	while(!ENT);
	sei();
#endif
			
			
	if (ee != EEP_FLAG)
	{
		_delay_ms(300);
		lcd_clear();
		_delay_ms(10);
		lcd_print("EEPROM!!");
		
		write_word(EEP_NR,4080);
		
		_write(EEP_KSP,2);
		_write(EEP_AWP,0);
		

	
		write_word(EEP_AL1,AL1);
		write_word(EEP_AL2,AL2);

		write_word(EEP_AKU_OFF,2048);
		write_word(EEP_POW_OFF,2048);
		


		_write(EEP_KCL,1);
		write_word(EEP_1_21,3440);
		write_word(EEP_1_20,3277);
		write_word(EEP_1_40,655);
		write_word(EEP_1_35,573);
		
		write_word(EEP_2_21,3440);
		write_word(EEP_2_20,3277);
		write_word(EEP_2_40,655);
		write_word(EEP_2_35,573);
		
		write_word(EEP_STN,stn);
		write_word(EEP_STW1,299);
		write_word(EEP_STW2,588);
		
		write_word(EEP_DATE,0x190F);		// 2012-08-15

#ifdef MEDIA_PS	
		write_word(EEP_SPRN,9800);
		write_word(EEP_SPRW,12000);
		write_word(EEP_PR_RANGE_L,9000);
		write_word(EEP_PR_RANGE_H,11000);
		write_word(EEP_RH_CORR,0);
		write_word(EEP_TM_CORR,0);
		
#elif MEDIA_PD
		write_word(EEP_SPRN,0);
		write_word(EEP_SPRW,1000);
		write_word(EEP_PR_RANGE_L,0);
		write_word(EEP_PR_RANGE_H,1000);

#endif
		_write(EEP_LCDM,1);
		_write(EEP_UOUT,0);
		

		_write(EEP_SH_FLAG,7);
		
		_write(EEP_PARAM,0);
		
		_write(0,EEP_FLAG);
		
		write_word(EEP_WORK_TIME,0);
		
		_delay_ms(1000);
	}

	Nr = read_word(EEP_NR);
	
	Ksp = _read(EEP_KSP);
	Awp = _read(EEP_AWP);
	AL1 = read_word(EEP_AL1);
	AL2 = read_word(EEP_AL2);
	Kcl = _read(EEP_KCL);
	U1_21 = read_word(EEP_1_21);
	U1_20 = read_word(EEP_1_20);
	U1_40 = read_word(EEP_1_40);
	U1_35 = read_word(EEP_1_35);
	
	U2_21 = read_word(EEP_2_21);
	U2_20 = read_word(EEP_2_20);
	U2_40 = read_word(EEP_2_40);
	U2_35 = read_word(EEP_2_35);
	
	stn = read_word(EEP_STN);
	stw1 = read_word(EEP_STW1);
	stw2 = read_word(EEP_STW2);
	
	uout = _read(EEP_UOUT);
	lcdmode = _read(EEP_LCDM);
	
	leg_date = read_word(EEP_DATE);
	
	time_cnt_h = read_word(EEP_WORK_TIME); 
	
#if defined(MEDIA_PS) || defined(MEDIA_RC)
	sh_flag = _read(EEP_SH_FLAG);
	pr_range_h = read_word(EEP_PR_RANGE_H);
	pr_range_l = read_word(EEP_PR_RANGE_L);
#endif
 
	param_trans = _read(EEP_PARAM);
	
	corr_rh = read_word(EEP_RH_CORR);
	corr_t = read_word(EEP_TM_CORR);
	
	a_off = read_word(EEP_AKU_OFF);
	p_off = read_word(EEP_POW_OFF);
}

void fuse2(char* str,u16 val)
{
	u16 dec = val / 100;
	char s[8];
	itoa(dec,s,10);
	strcpy(str,s);
	strcat(str,"."); 
	dec = val - (dec * 100);
	itoa(dec,s,10);
	if (dec < 10)
		strcat(str,"0");
	strcat(str,s);
}

void fuse1(char* str,u16 val)
{
	u16 dec = val / 10;
	char s[8];
	itoa(dec,s,10);
	strcpy(str,s);
	strcat(str,".");
	dec = val - (dec * 10);
	itoa(dec,s,10);
	strcat(str,s);
}

void fuse1i(char* str,i16 val)
{

	i16 val2 = val;

	itoa(val2,str,10);
	
	u8 len = strlen(str);
	str[len+1] = 0;
	str[len] = str[len-1];
	str[len-1] = '.';
}


#define CRC8INIT    0x00
#define CRC8POLY    0x18              //0X18 = X^8+X^5+X^4+X^0

uint8_t crc8( uint8_t *data, uint16_t number_of_bytes_in_data )
{
	uint8_t  crc;
	uint16_t loop_count;
	uint8_t  bit_counter;
	uint8_t  b;
	uint8_t  feedback_bit;

	crc = CRC8INIT;

	for (loop_count = 0; loop_count != number_of_bytes_in_data; loop_count++)
	{
		b = data[loop_count];

		bit_counter = 8;
		do {
			feedback_bit = (crc ^ b) & 0x01;

			if ( feedback_bit == 0x01 ) {
				crc = crc ^ CRC8POLY;
			}
			crc = (crc >> 1) & 0x7F;
			if ( feedback_bit == 0x01 ) {
				crc = crc | 0x80;
			}

			b = b >> 1;
			bit_counter--;

		} while (bit_counter > 0);
	}

	return crc;
}

void show_param()
{
	
	float ilad = 0;
	u16 lad = 0;
	
	u16 aku = v_aku + ( a_off - 2048);
	u16 pow = v_pow + ( p_off - 2048);
	
	
	if (pow > aku)
	{
		ilad = (float)(pow - aku) / 0.0056;
		lad = ilad ;
	}
	if (ilad < 4500)
	{
		ilad = 0;
	}

	
	char s[10];
	lcd_home();
	lcd_print("ZAS=");
	fuse1(s,pow / 100);
	if (ilad < 3000)
	{
		lcd_print(" 0.0");
	}
	else
	{
		lcd_print(s);
		lcd_print("  ");
	}
	WAITMS(2000);
	
	lcd_home();
	lcd_print("AKU=");
	fuse1(s,aku / 100);
	lcd_print(s);
	lcd_print("  ");
	WAITMS(2000);
	
	lcd_home();
	lcd_print("LAD=");
	
	
	fuse1(s,lad / 100);
	lcd_print(s);
	lcd_print("  ");
	WAITMS(2000);
#ifndef MEDIA_NO_PEL	
	lcd_home();
	lcd_print("Vkom=");
	fuse1(s,v_dc / 100);
	lcd_print(s);
	lcd_print("  ");
	WAITMS(2000);
#endif
	lcd_home();
	lcd_print("AWP ");
	if (Awp)
	{
		lcd_print("ZAL ");
	}
	else
	{
		lcd_print("WYL ");
	}
	WAITMS(1000);
	if (Awp)
	{
		display_alarms();
	}
	
	if (Ksp == 2)
	{
		lcd_home();
		lcd_print("WEJSCIE:");
		WAITMS(1000);
		lcd_home();
		if (PINA & (1 << 2))
		{
			lcd_print("OTWARTE ");
		}
		else
		{
			lcd_print("ZAMKNIE.");
		}
		WAITMS(1000);	
	}
	
#ifdef MEDIA_HASTEMP
	lcd_home();
	if (v_tmp & 0x8000)
	{
		lcd_print("T:-");
	}	
	else
	{
		lcd_print("T: ");
	}
	fuse1(s,v_tmp & 0x7FFF);
	lcd_print(s);
	lcd_print("  ");
	WAITMS(1000);
#endif	
	
	
	/// dodac AWP
	Pro = PRO_WORK;
}

void dac_clk()
{

	DAC_CLK_HI;
	WAITUS(50);
	DAC_CLK_LOW;
	WAITUS(30);

}

void dac_set()
{
	DAC_CLK_LOW;
	DAC_VCC_ON;
	
	DAC_CS_LOW;
	
	DAC_DIN_HI;
	dac_clk();
	DAC_DIN_LOW;
	dac_clk();
	DAC_DIN_HI;
	dac_clk();
	DAC_DIN_HI;
	dac_clk();
	
	for (i8 c = 11; c >= 0; c--)
	{
		if (napa & (1 << c))
		{
			DAC_DIN_HI;
		}
		else
		{
			DAC_DIN_LOW;
		}
		dac_clk();
	}
	
	DAC_CS_HI;
	WAITUS(100);
	DAC_CS_LOW;
	
	DAC_DIN_LOW;
	dac_clk();
	DAC_DIN_LOW;
	dac_clk();
	DAC_DIN_HI;
	dac_clk();
	DAC_DIN_HI;
	dac_clk();
	
	for (i8 c = 11; c >= 0; c--)
	{
		if (napb & (1 << c))
		{
			DAC_DIN_HI;
		}
		else
		{
			DAC_DIN_LOW;
		}
		dac_clk();
	}
	DAC_CS_HI;
}

#if defined(MEDIA_CH4) || defined(MEDIA_CH4IR)

void calc_dac_out()
{
	if (!uout)
	{
		napb = 0;
		napa = 0;
		return;
	}
	if (uout == 2)	// in calib;
		return;	
		
	u16 tmp = meas;
	
#ifdef MEDIA_CH4IR
	tmp &= 0xCFFF;
#endif
	
	float fnap;
		
	if (tmp & 0x8000)	//15bit
	{
		tmp &= 0x7FFF;
		
		if (tmp & 0x1000)
		{
			tmp &= 0x0FFF;
			
			if (tmp > 15)	//> -1.5%
			{
				napb = U2_35;
				napa = U1_35;
				return;
			}
			napb = U2_40;
			napa = U1_40;
			return;
		}
		if (tmp < 20)		//< 2.0%
		{
			napa = U1_40;
			napb = U2_40;
			return;
		}
		
		if (tmp <= 50)	// <= 5%
		{
			fnap = U1_20 - U1_40;
			fnap = fnap / 50 * tmp + U1_40;
			napa = fnap;
		}
		else
			napa = U1_21;
			
		if (tmp > 1000)
		{
			napb = U2_21;
			return;
		}			
			
		fnap = U2_20 - U2_40;
		fnap = (fnap / 1000) * tmp;
		napb = fnap  + U2_40;
		return;
	}		
		
	if (tmp & 0x4000)	// 14bit
	{
		tmp &= 0x3FFF;
		
		if (tmp & 0x1000)		// 12bit  - minus
		{
			tmp &= 0x0FFF;
			
			if (tmp < 20)		// -0.2%
			{
				napb = U2_40;
				napa = U1_40;
				return;
			}
			napa = U1_35;
			napb = U2_35;
			return;
		}
		tmp = meas & 0x0FFF;
		
		
		fnap =  ( U2_20 - U2_40 ) / 10000;
		fnap = fnap * tmp + U2_40;
		napb = fnap;
		
		
		if (tmp > 500)
		{
			napa = U1_21;
			return;
		}

		
		fnap = ( U1_20 - U1_40 ) / 500;
		fnap = fnap * tmp ;
		napa = fnap + U1_40;
	}			
		
		
}

#endif

void off_routine()
{
	lcd_home();
	
	if (PINA & 0x02)
	{
		
		lcd_print("  WYL ? ");
		
		for (u8 c = 0; c < 200; c++)
		{
			if (!PLU)
			{
				lcd_home();
				lcd_print("WYLACZAM");
				WAITMS(1000);
				PORTA &= ~(1 << 6);
				WAITMS(1000);
				PORTA |= ( 1 << 6);
			}
			WAITMS(20);
		}
		Pro = PRO_WORK;
	}
	else
	{
		lcd_print(" LINIA! ");
		WAITMS(2000);
		Pro = PRO_WORK;
	}	
}

#if defined(MEDIA_CH4) || defined(MEDIA_CH4IR)

void config_menu()
{
	char str[8];
		
	switch(calib_ptr_deep)
	{
		case 0x00:
		{
			lcd_home();
			lcd_print(" KONFIG ");
			WAITMS(1000);
			lcd_home();
			lcd_print("SET[-/+]");
			WAITMS(1000);
			calib_ptr_deep++;
			break;
		}
		case 0x01:
		{
			lcd_home();
			switch(Ksp)
			{
				case 0:
				lcd_print(" BRAK   ");
				break;
				case 1:
				lcd_print(" KSP-2  ");
				break;
				case 2:
				lcd_print(" KSP-3  ");
				break;
				
			}
			if (!PLU)
			{
				Ksp++;
			}
			
			if (!MIN)
			{
				Ksp--;
			}
			
			if (Ksp > 2)
			Ksp = 0;

			if (!ENT)
			{
				_write(EEP_KSP,Ksp);
				
				if (Ksp == 0 || Ksp == 1)
				{
					tk_data = 0;		// analog
					tk_addr = K_ADDR_KSP;
				}
				else
				{
					tk_data = 1;		// digtrans
					tk_addr = K_ADDR_KSP;
				}
				
				calib_ptr_deep++;
			}
			break;
		}
		case 0x02:
		{
			lcd_home();
			lcd_print("AWP ");
			if (Awp)
			{
				lcd_print("ZAL ");
			}
			else
			{
				lcd_print("WYL ");
			}
			if (!PLU)
			{
				Awp = 1;
			}
			if (!MIN)
			{
				Awp = 0;
			}
			if (!ENT)
			{
				_write(EEP_AWP,Awp);
				if (Awp)
				{
					calib_ptr_deep += 1;
				}
				else
				{
					calib_ptr_deep = 0x05;	// kcl
				}
			}
			break;
		}
		case 0x03:
		{
			lcd_home();
			lcd_print("AL1=");
			fuse2(str,AL1);
			lcd_print(str);
			lcd_print("  ");
			
			if (!PLU)
			AL1++;
			if (!MIN)
			AL1--;
			
			if (AL1 < 20)
			AL1 = 20;
			if (AL1 > 200)
			AL1 = 200;
			
			if (!ENT)
			{
				calib_ptr_deep++;
				write_word(EEP_AL1,AL1);
				if (AL1 >= AL2)
				{
					AL2 = AL1;
					write_word(EEP_AL2,AL2);
				}
			}
			break;
		}
		case 0x04:
		{
			lcd_home();
			lcd_print("AL2=");
			fuse2(str,AL2);
			lcd_print(str);
			lcd_print("  ");
			
			if (!PLU)
			AL2++;
			if (!MIN)
			AL2--;
			
			if (AL2 < AL1)
			AL2 = AL1;
			if (AL2 > 200)
			AL2 = 200;
			
			if (!ENT)
			{
				calib_ptr_deep++;
				write_word(EEP_AL2,AL2);
			}
			break;
		}
		case 0x05:
		{
			lcd_home();
			lcd_print("KCL ");
			if (Kcl)
			{
				lcd_print("ZAL ");
			}
			else
			{
				lcd_print("WYL ");
			}
			if (!PLU)
			{
				Kcl = 1;
			}
			if (!MIN)
			{
				Kcl = 0;
			}
			if (!ENT)
			{
				_write(EEP_KCL,Kcl);
				calib_ptr_deep += 1;

			}
			break;
		}
		case 0x06:
		{
			lcd_home();
			lcd_print("WY-U ");
			if (uout)
			{
				lcd_print("ZAL ");
			}
			else
			{
				lcd_print("WYL ");
			}
			if (!PLU)
			{
				uout = 1;
			}
			if (!MIN)
			{
				uout = 0;
			}
			if (!ENT)
			{
				_write(EEP_UOUT,uout);
				calib_ptr_deep += 1;

			}
			break;
		}		
		case 0x07:
		{
			lcd_home();
			lcd_print("LCD ");
			if (lcdmode)
			{
				lcd_print("ZAL ");
			}
			else
			{
				lcd_print("TIME");
			}
			if (!PLU)
			{
				lcdmode = 1;
			}
			if (!MIN)
			{
				lcdmode = 0;
			}
			if (!ENT)
			{
				_write(EEP_LCDM,lcdmode);
				calib_ptr_deep += 1;

			}
			break;
		}
		case 0x08:
		{
			lcd_home();
			lcd_print("ZAPISANE");

			WAITMS(2000);
			
			Pro = PRO_WORK;
			intro();
			break;
		}
	}
	
	if (!PLU || !MIN)
	{
		WAITMS(100);
	}
	
	while( !ENT);
	
}

#endif

void load_routine()
{
	CUR_SW_HIGH;
	char napis[74];
	strcpy(napis,"Ladowanie aku....PKiMSA CARBOAUTOMATYKA.S.A....");
	resetStartTimer();
	tp_addr = P_ADDR_DCOFF;
	
	PORTA &= ~(1 << 6);
	while(1)
	{
		lcd_home();
		u8 len = strlen(napis);
		char str[10];
		for (u8 c = 0; c < len - 8; c++)
		{
			lcd_home();
			for (u8 x = 0; x < 8; x++)
			str[x] = napis[x + c];
			str[8] = 0;
			lcd_print(str);
			WAITMS(100);
			LED_W_ON;
			WAITMS(25);
			LED_W_OFF;
		}
		WAITMS(500);
		u16 aku = v_aku + ( a_off - 2048);
		u16 pow = v_pow + ( p_off - 2048);

		fuse2(str,aku / 10);
		lcd_home();
		lcd_print("  AKU=  ");
		WAITMS(500);
		lcd_home();
		lcd_print(" ");
		lcd_print(str);
		lcd_print("V ");
		WAITMS(1400);
		lcd_home();
		lcd_print("  Czas:  ");
		WAITMS(500);
		
		u8 hour,min,sek;
		sek = (TCNT1 / 1024 ) % 60;
		hour = TimerH / 60;
		min = TimerH % 60;
		
		itoa(hour,str,10);
		lcd_home();
		//lcd_print(" ");
		lcd_print(str);
		lcd_print(":");
		itoa(min,str,10);
		lcd_print(str);
		lcd_print(":");
		
		itoa(sek,str,10);
		lcd_print(str);
		lcd_print("s  ");
		WAITMS(1400);
		
		float ilad = 0;
		u16 lad = 0;
		

		if (pow > aku)
		{
			ilad = (float)(pow - aku) / 0.0056;
			lad = ilad ;
		}
		
		fuse2(str,lad / 10);
		lcd_home();
		lcd_print(" ");
		lcd_print(str);
		lcd_print("mA  ");
		WAITMS(2000);

	}
}

void blink_led()
{
	if ((PORTD & 0xC0) != 0xC0)		// alarms on
	{
		if (!(PORTD & (1 << 7)))
		{
			LED_A_ON;
			WAITMS(9);
			LED_A_OFF;
			WAITMS(45);
					
		}
		LED_A_ON;
	}
	WAITMS(9);
	LED_A_OFF;
	LED_W_ON;
	WAITMS(15);
	LED_W_OFF;
			
	if (!(PINA & (1 << 2)))
	{
		WAITMS(25);
		LED_W_ON;
		WAITMS(25);
		LED_W_OFF;
		WAITMS(25);
		LED_W_ON;
		WAITMS(25);
		LED_W_OFF;
	}
			
	if (ksp_error)
	{
		ksp_error = 0;
		lcd_home();
		lcd_print("ZAP/KSP3");
		init_display = 1;
		WAITMS(3000);
	}
}